package com.cloudpivot.receivales.esign.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cloudpivot.receivales.ding.basic.service.impl.HttpAPIServiceForDing;
import com.cloudpivot.receivales.esign.domain.FileEntity;
import com.cloudpivot.receivales.esign.domain.MessageEntity;
import com.cloudpivot.receivales.esign.domain.SignersEntity;
import com.cloudpivot.receivales.esign.service.ESignService;
import com.cloudpivot.receivales.esign.utils.HttpUtilNew;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class ESignServiceImpl implements ESignService {

    @Autowired
    private HttpAPIServiceForDing httpAPIServiceForDing;

    @Value("${myprops.bpmapiurl}")
    private String bpmApiURL;

    @Value("${myprops.crmurl}")
    private String CRMURL;

    @Value("${esign.appconfig.workorder.appid}")
    private String workOrderAppid;

    @Value("${esign.appconfig.workorder.secret}")
    private String workOrderSecret;

    //E签宝地址
    @Value("${esign.openapi}")
    private String openapi;

    //获取token的url
    @Value("${esign.api.token}")
    private String tokenurl;

    //上传文件的url
    @Value("${esign.api.fileupload}")
    private String fileuploadurl;

    //检查文件状态的url
    @Value("${esign.api.checkfile}")
    private String checkfileurl;

    //发起签署流程的url
    @Value("${esign.api.createflow}")
    private String createflowurl;

    //获取签署的url
    @Value("${esign.api.getsignurl}")
    private String getsignurl;

    //下载签署后文件的url
    @Value("${esign.api.downloadfile}")
    private String downloadfileurl;

    //获取签字坐标的url
    @Value("${esign.api.keywordpositions}")
    private String keywordpositionsurl;

    //短信服务url
    @Value("${messageService.url}")
    private String messageServiceUrl;
    @Value("${messageService.appid}")
    private String messageServiceAppid;
    @Value("${messageService.key}")
    private String messageServiceKey;
    @Value("${messageService.signature}")
    private String messageServiceSignature;//短信抬头

    private HttpUtilNew httpUtilNew;

    private final ConcurrentHashMap<String, String> tokenStore = new ConcurrentHashMap<>();

    private final String content = "请您仔细审阅本次服务所提供的全部内容，确保其符合您的要求与期望后，签字以示确认，签署链接：%s";

    @Override
    public MessageEntity startFlow(MultipartFile file, JSONObject bodyJSON) throws Exception {
        MessageEntity message = new MessageEntity();
        FileEntity fileEntity = new FileEntity();

        // 创建临时文件
        File tempFile = File.createTempFile("temp", null);
        // 将 MultipartFile 的内容转存到临时文件
        file.transferTo(tempFile);
        // 从临时文件中获取 FileInputStream
        FileInputStream inputStream = new FileInputStream(tempFile);

        //文件名称
        fileEntity.setFileName(file.getOriginalFilename());
        log.info("文件名："+fileEntity.getFileName());
        //文件字节大小
        fileEntity.setFileSize(String.valueOf(file.getSize()));
        //文件Content-MD5值：先获取文件MD5的128位二进制数组，再对此二进制进行Base64编码。
        fileEntity.setFileContentMD5(getFileContentMD5(inputStream));
        //文件MIME类型
        fileEntity.setFileContentType(file.getContentType());

        // 处理完文件后，删除临时文件
        tempFile.deleteOnExit();

        /**
        *第一步：获取token
         */
        MessageEntity getTokenMessage = getToken();
        if(getTokenMessage.getCode() != 0){
            return getTokenMessage;
        }
        String token = getTokenMessage.getMessage();
        log.info("获取到的token："+token);

        /**
         *第二步：获取文件上传地址
         */
        String getFileUploadUrlResult = getFileUploadUrl(fileEntity, token);
        JSONObject getFileUploadUrlResultObject = JSONObject.parseObject(getFileUploadUrlResult);
        if(getFileUploadUrlResultObject.getInteger("code") != 0){
            message.setCode(getFileUploadUrlResultObject.getInteger("code"));
            message.setMessage("获取文件上传地址异常："+getFileUploadUrlResultObject.getString("message"));
            return message;
        }
        //取到返回的地址
        JSONObject getFileUploadUrlResultObjectData = getFileUploadUrlResultObject.getJSONObject("data");
        String fileUploadUrl = getFileUploadUrlResultObjectData.getString("fileUploadUrl");        //文件需要上传到的地址
        String fileId = getFileUploadUrlResultObjectData.getString("fileId");        //文件存在E签宝的id

        fileEntity.setFileId(fileId);
        log.info("获取到的fileUploadUrl："+fileUploadUrl);

        /**
         *第三步：上传文件流
         */
        String fileUploadResult = fileUpload(fileEntity, fileUploadUrl, inputStream);
        JSONObject fileUploadResultObject = JSONObject.parseObject(fileUploadResult);
        if(fileUploadResultObject.getInteger("errCode") != 0){
            message.setCode(fileUploadResultObject.getInteger("errCode"));
            message.setMessage("上传文件流异常："+fileUploadResultObject.getString("msg"));
            return message;
        }

        /**
         * 第四步：查询文件是否上传/转换PDF成功
         */
        MessageEntity fileCheckMessage = fileCheck(token, fileEntity.getFileId());
        if(fileCheckMessage.getCode() != 0){
            message.setCode(fileCheckMessage.getCode());
            message.setMessage("查询文件是否上传/转换PDF成功，异常："+fileCheckMessage.getMessage());
            return message;
        }

        /**
         * 第五步：基于文件发起签署
         */
        SignersEntity[] signers = JSON.parseObject(bodyJSON.getString("signers"), SignersEntity[].class);
        String createByFileResult = createByFile(fileEntity, token, signers, bodyJSON.getString("signFlowTitle"), bodyJSON.getString("notifyUrl"));
        JSONObject createByFileResultObject = JSONObject.parseObject(createByFileResult);
        if(createByFileResultObject.getInteger("code") != 0){
            message.setCode(createByFileResultObject.getInteger("code"));
            message.setMessage("基于文件发起签署异常："+createByFileResultObject.getString("message"));
            return message;
        }
        String signFlowId = createByFileResultObject.getJSONObject("data").getString("signFlowId");

        /**
         *第六步：获取签署链接、发送短信提醒
         */
        for(SignersEntity  signer: signers){
            String getSignUrlResult = getSignUrl(signer.getPsnMobile(), signFlowId, token);
            JSONObject getSignUrlResultObject = JSONObject.parseObject(getSignUrlResult);
            if(getSignUrlResultObject.getInteger("code") != 0){
                message.setCode(getSignUrlResultObject.getInteger("code"));
                message.setMessage("获取签署链接异常（"+signer.getPsnName()+"）："+getSignUrlResultObject.getString("message"));
                return message;
            }
            String signurl = getSignUrlResultObject.getJSONObject("data").getString("shortUrl");

            //短信内容
            String finalContent = String.format(content, signurl);
            String postMessageResult = postMessageToMobile(signer.getPsnMobile(), URLEncoder.encode(finalContent, StandardCharsets.UTF_8.name()));
            JSONObject postMessageResultObject = JSONObject.parseObject(postMessageResult);
            if(!postMessageResultObject.getString("result").equals("SUCCESS")){
                message.setCode(-1);
                message.setMessage("发送短信提醒异常（"+signer.getPsnName()+"）："+postMessageResultObject.getString("message"));
                return message;
            }
        }

        JSONObject flowCreateResultJSON = new JSONObject();
        flowCreateResultJSON.put("signFlowId",signFlowId);
        flowCreateResultJSON.put("fileId",fileId);

        message.setCode(0);
        message.setMessage("签署流程已成功发起");
        message.setData(flowCreateResultJSON.toJSONString());
        return message;
    }

    /**
     * 获取token
     */
    @Override
    public MessageEntity getToken() {
        String url = openapi+tokenurl+"?appId="+workOrderAppid+"&secret="+workOrderSecret+"&grantType=client_credentials";
        log.info("请求的URL："+url);

        MessageEntity message = new MessageEntity();
        String tokenJSON = tokenStore.get("ESignToken");
        String token;

        if(StringUtils.isBlank(tokenJSON)){
            log.info("内存中不存在token，重新获取token......");
            String getTokenResult = httpUtilNew.sendGet(url, "", "", true);
            JSONObject getTokenResultObject = JSONObject.parseObject(getTokenResult);
            if(getTokenResultObject.getInteger("code") != 0){
                message.setCode(getTokenResultObject.getInteger("code"));
                message.setMessage("获取token异常："+getTokenResultObject.getString("message"));
                return message;
            }
            //取到返回的token
            JSONObject getTokenResultObjectData = getTokenResultObject.getJSONObject("data");
            token = getTokenResultObjectData.getString("token");
            String expiresIn = getTokenResultObjectData.getString("expiresIn");//token 访问令牌有效期截止时间（毫秒时间戳）

            tokenJSON = "{\"token\":\""+token+"\",\"expiresIn\":\""+expiresIn+"\"}";
            tokenStore.put("ESignToken",tokenJSON);

            log.info("token获取正常......");

            message.setCode(0);
            message.setMessage(token);
            return message;
        }

        JSONObject tokenJSONObject = JSONObject.parseObject(tokenJSON);
        // 获取当前的本地时间戳
        long currentTime = System.currentTimeMillis();
        long timestampToCheck = Long.parseLong(tokenJSONObject.getString("expiresIn")) - (5*60*1000);

        // 检查本地时间是否超过时间戳
        if (currentTime > timestampToCheck) {
            log.info("本地时间已经超过了token的过期时间，重新获取token......");
            String getTokenResult = httpUtilNew.sendGet(url, "", "", true);
            JSONObject getTokenResultObject = JSONObject.parseObject(getTokenResult);
            if(getTokenResultObject.getInteger("code") != 0){
                message.setCode(getTokenResultObject.getInteger("code"));
                message.setMessage("获取token异常："+getTokenResultObject.getString("message"));
                return message;
            }
            //取到返回的token
            JSONObject getTokenResultObjectData = getTokenResultObject.getJSONObject("data");
            token = getTokenResultObjectData.getString("token");
            String expiresIn = getTokenResultObjectData.getString("expiresIn");//token 访问令牌有效期截止时间（毫秒时间戳）

            tokenJSON = "{\"token\":\""+token+"\",\"expiresIn\":\""+expiresIn+"\"}";
            tokenStore.put("ESignToken",tokenJSON);

            log.info("token获取正常......");

            message.setCode(0);
            message.setMessage(token);
            return message;
        }

        log.info("当前内存中token状态正常......");
        token = tokenJSONObject.getString("token");
        message.setCode(0);
        message.setMessage(token);
        return message;
    }

    /**
     * 获取文件上传地址
     */
    @Override
    public String getFileUploadUrl(FileEntity fileEntity, String token) {

        JSONObject postJSON = new JSONObject();
        postJSON.put("contentMd5",fileEntity.getFileContentMD5());
        postJSON.put("contentType",fileEntity.getFileContentType());
        postJSON.put("convertToPDF",true);
        postJSON.put("fileName",fileEntity.getFileName());
        postJSON.put("fileSize",fileEntity.getFileSize());

        String url = openapi+fileuploadurl;

        String result = httpUtilNew.sendPost(url, postJSON.toJSONString(), workOrderAppid, token);

        return result;
    }

    /**
     * 上传文件流
     */
    @Override
    public String fileUpload(FileEntity fileEntity, String fileUploadUrl, FileInputStream inputStream) {

        String ContentType = fileEntity.getFileContentType();
        String ContentMD5 = fileEntity.getFileContentMD5();

        String result = httpUtilNew.sendPut(fileUploadUrl, inputStream, ContentMD5, ContentType);

        return result;
    }

    /**
     * 查询文件是否上传/转换PDF成功
     */
    @Override
    public MessageEntity fileCheck(String token, String fileId) {

        MessageEntity message = new MessageEntity();

        String url = openapi+checkfileurl+fileId;

        String result = httpUtilNew.sendGet(url, workOrderAppid, token, false);

        JSONObject fileCheckResultObject = JSONObject.parseObject(result);
        if(fileCheckResultObject.getInteger("code") != 0){
            message.setCode(fileCheckResultObject.getInteger("code"));
            message.setMessage("第四步：查询文件是否上传/转换PDF成功，异常："+fileCheckResultObject.getString("message"));
            return message;
        }

        fileCheckResultObject.getJSONObject("data").getString("fileDownloadUrl");
        int fileStatus = fileCheckResultObject.getJSONObject("data").getInteger("fileStatus");

        if(fileStatus == 5){
            log.info("文件已上传并转换PDF成功！");
            message.setCode(0);
            message.setMessage("文件已上传并转换PDF成功！");
            return message;
        }

        try {
            log.info("文件未转换完成，等待重新尝试......");
            TimeUnit.MILLISECONDS.sleep(500);
            return fileCheck(token, fileId);
        } catch (InterruptedException e) {
            e.printStackTrace();

            message.setCode(-1);
            message.setMessage("线程等待异常");
            return message;
        }

    }

    /**
     * 基于文件发起签署
     */
    @Override
    public String createByFile(FileEntity fileEntity, String token, SignersEntity[] signers, String signFlowTitle, String notifyUrl) {
        SignersEntity[]  resultSigners = getKeywordPositions(fileEntity.getFileId(), token, signers);
        if(resultSigners == null){
            JSONObject message = new JSONObject();
            message.put("code", -1);
            message.put("message", "获取签字的具体页数及坐标异常");
            return message.toJSONString();
        }

        //最终推送json对象
        JSONObject postJSON = new JSONObject();

        //文件json对象
        JSONObject fileJSON = new JSONObject();
        fileJSON.put("fileId", fileEntity.getFileId());
        fileJSON.put("fileName", fileEntity.getFileName());
        //将文件json对象放入文件对象数组
        JSONArray fileJSONArray = new JSONArray();
        fileJSONArray.add(fileJSON);

        //签署流程配置对象
        JSONObject signFlowConfigJSON = new JSONObject();
        signFlowConfigJSON.put("signFlowTitle", signFlowTitle);
        signFlowConfigJSON.put("autoStart", true);
        signFlowConfigJSON.put("autoFinish", true);
        signFlowConfigJSON.put("signConfig", JSONObject.parseObject("{ \"availableSignClientTypes\":\"1\"}"));
        signFlowConfigJSON.put("noticeConfig", JSONObject.parseObject("{ \"noticeTypes\":\"\"}"));
        //signFlowConfigJSON.put("authConfig",  JSONObject.parseObject("{\"willingnessAuthModes\":[\"CODE_SMS\"],\"psnAvailableAuthModes\":[\"PSN_MOBILE3\"]}"));
        signFlowConfigJSON.put("authConfig",  JSONObject.parseObject("{\"willingnessAuthModes\":[\"CODE_SMS\"]}"));
        signFlowConfigJSON.put("notifyUrl",notifyUrl);

        //签署人对象数组
        JSONArray signersJSONArray = new JSONArray();
        //确认所有签署人json对象
        for(SignersEntity signer : resultSigners){
            //此签署人json对象
            JSONObject signerJSON = new JSONObject();

            //signFields
            JSONArray signFieldsJSONArray = new JSONArray();
            String signFieldsStr =
                    "{\"customBizNum\": \"orderSignTest\"," +
                        "\"fileId\": \""+fileEntity.getFileId()+"\"," +
                        "\"normalSignFieldConfig\":{" +
                            "\"psnSealStyles\": \"0\"," +
                            "\"signFieldStyle\":1," +
                            "\"signFieldPosition\":{" +
                                "\"positionPage\":\""+signer.getPositionPageNum()+"\"," +
                                "\"positionX\":"+signer.getPositionX()+"," +
                                "\"positionY\":"+signer.getPositionY()+"" +
                            "}" +
                        "}" +
                    "}";
            signFieldsJSONArray.add(JSONObject.parseObject(signFieldsStr));

            String psnSignerInfoStr =
                    "{\"psnAccount\":\""+signer.getPsnMobile()+"\"," +
                        "\"psnInfo\":{" +
                            "\"psnName\":\""+signer.getPsnName()+"\"," +
                            "\"psnMobile\":\""+signer.getPsnMobile()+"\"" +
                        "}" +
                    "}";

            signerJSON.put("signerType",0);
            signerJSON.put("signFields",signFieldsJSONArray);
            signerJSON.put("psnSignerInfo",JSONObject.parseObject(psnSignerInfoStr));
            signerJSON.put("signConfig",JSONObject.parseObject("{ \"signOrder\":\""+signer.getSignOrder()+"\",\"agreeSkipWillingness\":true}"));

            //将签署人json对象放入签署人对象数组
            signersJSONArray.add(signerJSON);
        }


        //将文件对象数组放入最终推送json对象
        postJSON.put("docs", fileJSONArray);
        //将签署流程配置对象放入最终推送json对象
        postJSON.put("signFlowConfig", signFlowConfigJSON);
        //将签署人对象数组放入最终推送json对象
        postJSON.put("signers", signersJSONArray);

        String url = openapi+createflowurl;

        log.info("发起签署的json字符串："+postJSON.toJSONString());
        String result = httpUtilNew.sendPost(url, postJSON.toJSONString(), workOrderAppid, token);

        return result;
    }


    /**
     * 获取签字的具体页数及坐标
     */
    @Override
    public SignersEntity[] getKeywordPositions(String fileId, String token, SignersEntity[] signers) {
        JSONObject postJSON = new JSONObject();

        JSONArray keywords = new JSONArray();
        for(SignersEntity signer : signers){
            keywords.add(signer.getPositionKeywords());
        }
        postJSON.put("keywords",keywords);

        String url = openapi+String.format(keywordpositionsurl, fileId);

        String result = httpUtilNew.sendPost(url, postJSON.toJSONString(), workOrderAppid, token);
        JSONObject resultObject = JSONObject.parseObject(result);
        if(resultObject.getInteger("code") != 0){
            return null;
        }
        log.info("确认关键词对应的XY轴位置，返回值："+result);
        //确认关键词对应的XY轴位置
        JSONArray keywordPositions = resultObject.getJSONObject("data").getJSONArray("keywordPositions");
        for(int i = 0; i < keywordPositions.size(); i++){
            JSONObject Object = keywordPositions.getJSONObject(i);

            for(SignersEntity signer : signers){
                if(Object.getString("keyword").equals(signer.getPositionKeywords())){
                    JSONObject thisKeywordPosition = Object.getJSONArray("positions").getJSONObject(0);
                    int pageNum = thisKeywordPosition.getInteger("pageNum");
                    int positionX = Math.round(thisKeywordPosition.getJSONArray("coordinates").getJSONObject(0).getFloat("positionX"));
                    int positionY = Math.round(thisKeywordPosition.getJSONArray("coordinates").getJSONObject(0).getFloat("positionY"));
                    signer.setPositionPageNum(pageNum);
                    signer.setPositionX(positionX+80);
                    signer.setPositionY(positionY+10);
                    break;
                }
            }

        }

        return signers;
    }


    /**
     * 下载签署完成后的文件
     */
    @Override
    public MessageEntity fileDownload(String signFlowId) {

        MessageEntity fileDownloadMessage = new MessageEntity();

        MessageEntity getTokenMessage = getToken();
        if(getTokenMessage.getCode() != 0){
            return getTokenMessage;
        }
        String token = getTokenMessage.getMessage();

        String url = openapi+String.format(downloadfileurl, signFlowId);
        log.info("下载签署完成后的文件，请求URL："+url);
        log.info("下载签署完成后的文件，token："+token);

        String fileDownloadResult = httpUtilNew.sendGet(url, workOrderAppid, token, false);
        JSONObject fileDownloadResultObject = JSONObject.parseObject(fileDownloadResult);

        if(fileDownloadResultObject.getInteger("code") != 0){
            fileDownloadMessage.setCode(fileDownloadResultObject.getInteger("code"));
            fileDownloadMessage.setMessage("下载签署完成后的文件，异常："+fileDownloadResultObject.getString("message"));
            return fileDownloadMessage;
        }

        JSONArray  files = fileDownloadResultObject.getJSONObject("data").getJSONArray("files");
        String downloadUrl = files.getJSONObject(0).getString("downloadUrl");

        fileDownloadMessage.setCode(0);
        fileDownloadMessage.setMessage("获取成功");
        fileDownloadMessage.setData("{\"downloadUrl\":\""+downloadUrl+"\"}");

        return fileDownloadMessage;
    }


    /***
     * 计算文件的Content-MD5
     * @param fis 文件路径
     * @return
     */
    private static String getFileContentMD5(FileInputStream fis) {
        // 获取文件MD5的二进制数组（128位）
        byte[] bytes = getFileMD5Bytes128(fis);
        // 对文件MD5的二进制数组进行base64编码
        return new String(Base64.encodeBase64(bytes));
    }

    /***
     * 获取文件MD5-二进制数组（128位）
     *
     * @param fis
     * @return
     * @throws IOException
     */
    private static byte[] getFileMD5Bytes128(FileInputStream fis) {
        //FileInputStream fis = null;
        byte[] md5Bytes = null;
        try {
            //File file = new File(filePath);
            //fis = new FileInputStream(file);
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] buffer = new byte[1024];
            int length = -1;
            while ((length = fis.read(buffer, 0, 1024)) != -1) {
                md5.update(buffer, 0, length);
            }
            md5Bytes = md5.digest();
            //fis.close();
        } catch (FileNotFoundException e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        } catch (IOException e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
        return md5Bytes;
    }


    /**
     * E签宝返回的附件推送至CRM
     */
    @Override
    public String pushReportToCRM(String signFlowId){
        try {
            //获取E签宝返回的下载地址
//            String url=String.format("%s%s",signservice,"eSign/fileDownload?signFlowId="+signFlowId);
//            String result = HttpUtilNew.oAGet(url);
//            JSONObject fileDownloadResultObject = JSONObject.parseObject(result);
//            log.info("downloadUrlResult："+fileDownloadResultObject.toJSONString());
//            if(fileDownloadResultObject.getInteger("code") != 0){
//                return "下载签署完成后的文件，异常："+fileDownloadResultObject.getString("message");
//            }
//            String downloadUrl = fileDownloadResultObject.getJSONObject("data").getString("downloadUrl");
//            log.info("downloadUrl："+downloadUrl);
            MessageEntity resultMessage = fileDownload(signFlowId);
            if(resultMessage.getCode() != 0){
                return "下载签署完成后的文件，异常："+resultMessage.getMessage();
            }
            JSONObject downloadUrlJSON = JSONObject.parseObject(resultMessage.getData());
            //获取E签宝返回的签署文件并将其转为 Base64 字符串
            String fileBaseString=HttpUtilNew.downloadFileAsBase64(downloadUrlJSON.getString("downloadUrl"));

            //获取signFlowId对应的工单id
            String crmurl = CRMURL + "new_work_orders?$select=new_name&$filter=new_signflowid_esign eq '"+signFlowId+"'";
            String ret = httpAPIServiceForDing.doGetCrm(new URI(null, crmurl, null).toURL().toString());
            JSONObject retObject = JSONObject.parseObject(ret).getJSONArray("value").getJSONObject(0);
            String workOrderid  = retObject.getString("new_work_orderid");

            //推送base64文件到对应CRM工单
            JSONObject reqJson = new JSONObject();
            reqJson.put("objecttypecode", "new_work_order");
            reqJson.put("objectid_new_work_order@odata.bind", "/new_work_orders(" + workOrderid + ")");
            reqJson.put("isdocument", true);
            reqJson.put("filename", "reportSignFinish.pdf");
            reqJson.put("documentbody", fileBaseString);
            String annotationurl = CRMURL + "annotations";
            String annotationRet = httpAPIServiceForDing.doPostCrm(annotationurl, reqJson.toJSONString(),"");
            JSONObject annotationResultObject = JSONObject.parseObject(annotationRet);
            String annotationid = annotationResultObject.getString("annotationid");
            log.info("新增附件成功-> guid：{}", annotationid);

            //更新CRM，并允许完工
            JSONObject updateObject=new JSONObject();
            //是否已上传附件
            updateObject.put("new_upload",true);
            //发送修改请求
            httpAPIServiceForDing.doPostCrm(CRMURL+"new_work_orders("+workOrderid+")", updateObject.toJSONString(),"");

            return annotationid;

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * E签宝返回的附件推送至BPM
     */
    @Override
    public String pushReportToBPM(String signFlowId){
        try {
            MessageEntity resultMessage = fileDownload(signFlowId);
            if(resultMessage.getCode() != 0){
                return "下载签署完成后的文件，异常："+resultMessage.getMessage();
            }
            JSONObject downloadUrlJSON = JSONObject.parseObject(resultMessage.getData());
            //获取E签宝返回的签署文件并将其转为 Base64 字符串
            String fileBaseString=HttpUtilNew.downloadFileAsBase64(downloadUrlJSON.getString("downloadUrl"));

            JSONObject pushObject = new JSONObject();
            pushObject.put("signFlowId", signFlowId);
            pushObject.put("base64", fileBaseString);

            String userRet = httpAPIServiceForDing.doPost(bpmApiURL+"/api/api/EquipmentInstall/backEnd/uploadReportToForm", pushObject.toJSONString(), null);

            return userRet;

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    @Override
    public String getSignUrl(String mobile, String signFlowId, String token) {
        String url = openapi +String.format(getsignurl, signFlowId);

        JSONObject operatorJSON = new JSONObject();
        operatorJSON.put("psnAccount", mobile);

        JSONObject postJSON = new JSONObject();
        postJSON.put("needLogin", false);
        postJSON.put("urlType", 2);
        postJSON.put("operator", operatorJSON);
        String result = httpUtilNew.sendPost(url, postJSON.toJSONString(), workOrderAppid, token);

        return result;
    }

    /**
     * 通过博圣短信服务发送短信
     */
    @Override
    public String postMessageToMobile(String mobile, String content){
        String url = messageServiceUrl+"?appid="+messageServiceAppid+"&signature="+messageServiceSignature+"&key="+messageServiceKey+"&mobile="+mobile+"&content="+content;

        String result = httpUtilNew.sendPost(url);

        return result;
    }
}
